/* eslint-disable @typescript-eslint/no-unused-vars */
import { defineStore } from 'pinia'
import { RouteRecordRaw } from 'vue-router'
import { DefineComponent } from 'vue'
// import { resolve } from 'path-browserify'
import { login, loginParams, refreshToken, getInfo, getRouters, logout } from '@/api/user'
import { setExpiresIn, setRefreshToken, setToken, setTokenType, getToken, getCompany, setCompany, getExpiresIn, getTokenType, getRefreshToken } from '@/utils/auth'
import Layout from '@/layout/index.vue'
import { routes } from '@/router/index'
import useRouters from '@/store/modules/router'

const viewModlues = import.meta.glob('../../views/**/*.{vue,tsx}')
const notFound = () => import('../../views/404.vue')
interface userState {
	token: string;
	expiresIn: number;
	tokenType: string;
	refreshToken: string;
	roles: Array<string>;
	user: Record<string, any>;
	permissions: string[];
  loginLoading: boolean,
  company:string,
  companyOptions:Array<any>
}
/**
 * @description: 路由组件路径
 * @param {string} view
 * @return {路由路径} routerPath
 */
const loadView = (viewPath: string) => viewModlues[`../../views/${ viewPath }`]

interface Token {
	accessToken: string;
	expiresIn: number;
	tokenType: string;
	refreshToken: string;
}
export type newRouteRecordRaw = RouteRecordRaw & {
	hidden: boolean;
	children?: newRouteRecordRaw[];
	component?: any;
	meta: {
		title: string;
		breadcrumb: string;
	};
};

const userStore = defineStore('user', {
  // other options...
  state():userState {
    return {
      token: getToken() || '',
      expiresIn: Number(getExpiresIn()) || 0,
      tokenType: getTokenType() || '',
      refreshToken: getRefreshToken() || '',
      permissions: [],
      roles: [],
      user: {},
      loginLoading: false,
      company: getCompany(),
      companyOptions: [],
    }
  },
  actions: {
    setTokey(token: string) {
      this.token = token
      setToken(token)
    },
    setExpiresIn(expiresIn: number) {
      setExpiresIn(expiresIn)
      this.expiresIn = expiresIn
    },
    setTokenType(tokenType: string) {
      setTokenType(tokenType)
      this.tokenType = tokenType
    },
    setCompany(company) {
      this.company = company
      setCompany(company)
    },
    setRefreshToken(refreshToken: string) {
      setRefreshToken(refreshToken)
      this.refreshToken = refreshToken
    },
    allSet({ accessToken, expiresIn, tokenType, refreshToken }: Token) {
      this.setTokey(accessToken)
      this.setExpiresIn(expiresIn)
      this.setTokenType(tokenType)
      this.setRefreshToken(refreshToken)
    },
    async login(data: loginParams) {
      try {
        const res: any = await login(data)
        const { access_token: accessToken, expires_in: expiresIn, token_type: tokenType, refresh_token: refreshToken, company_id: companyId, company_list: companyList } = res
        if (res.access_token) {
          this.allSet({ accessToken, expiresIn, tokenType, refreshToken })
          if (Array.isArray(companyList) && companyList.length === 1) {
            this.companyOptions = companyList
            this.setCompany(companyId)
          }
          return Promise.resolve()
        }
        return Promise.reject()
      } catch (error) {
        return Promise.reject(error)
      }
    },
    async handRefreshToken() {
      try {
        if (!this.refreshToken) return Promise.reject()
        const res = await refreshToken(this.refreshToken)
        const { access_token: accessToken, expires_in: expiresIn, token_type: tokenType, refresh_token: refreshTokenKey } = res
        if (res.access_token) {
          this.allSet({ accessToken, expiresIn, tokenType, refreshToken: refreshTokenKey })
          return Promise.resolve()
        }
        return Promise.resolve(undefined)
      } catch (error) {
        return Promise.reject(error)
      }
    },
    getInfo() {
      return getInfo().then((res) => {
        const { user, permissions, roles } = res.data
        this.user = user
        this.permissions = permissions
        this.roles = roles
        return res
      }) 
    },
    generateRoutes() {
      const routers = useRouters()
      return getRouters().then((res: { [key: string]: string | object }) => {
        const accessedRoutes = filterAsyncRouter(JSON.parse(JSON.stringify(res.data)), false, true)
        const sidebarRoutes = filterAsyncRouter(JSON.parse(JSON.stringify(res.data)))
        routers.setAccessedRoutes(routes.concat(accessedRoutes))
        routers.setSidebarRoutes(routes.concat(sidebarRoutes))
        return accessedRoutes
      }) 
    },
    clearToken() {
      const routers = useRouters()
      this.allSet({ accessToken: '', expiresIn: 0, refreshToken: '' })
      this.setCompany('')
      this.roles = []
      routers.setAccessedRoutes([])
      routers.setSidebarRoutes([])
      return Promise.resolve(true)
    },
    fedLogOut() {
      return logout().then(() => {
        this.clearToken().then(() => Promise.resolve(true))
      })
    },
    setLoginLoading(v) {
      this.loginLoading = v
    },
  },
})
// 遍历后台传来的路由字符串，转换为组件对象
function filterAsyncRouter(asyncRouterMap: newRouteRecordRaw[], lastRouter = false, type = false): newRouteRecordRaw[] {
  return asyncRouterMap.filter((route: newRouteRecordRaw) => {
    if (type && route.children) {
      route.children = castToFlatRoute(route.children, '', [], route.meta.title)
    }
    if (route.component) {
      // Layout ParentView 组件特殊处理
      if (route.component === 'Layout') {
				Layout as DefineComponent
				route.component = Layout
      } else if (route.component === 'routerView') {
        // route.component = routerView;
      } else if (typeof route.component === 'string') {
        route.component = loadView(route.component) || notFound
      }
    }
    if (route.children != null && route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children, Boolean(route), type)
    } else {
      delete route.children
      delete route.redirect
    }
    const regexp = /^https?/gi
    if (type) {
      if (regexp.test(route.path)) return false
    } else if (route.hidden) return false
    return true
  })
}
/**
 * 将子路由转换为扁平化路由数组（仅一级）
 * @param {待转换的子路由数组} routes
 * @param {父级路由路径} parentPath
 */
function castToFlatRoute(routes: newRouteRecordRaw[], parentPath: string, flatRoutes: newRouteRecordRaw[] = [], parentName: string) {
  routes.forEach((route: any) => {
    if (route.children && route.children.length) {
      route.meta.breadcrumb = parentName
      castToFlatRoute(route.children, `${ parentPath }/${ route.path }`, flatRoutes, `${ parentName }/${ route.meta.title }`)
    } else {
      route.meta.breadcrumb = `${ parentName }/${ route.meta.title }`
      flatRoutes.push({ ...route, path: (`${ parentPath }/${ route.path }`).substring(1) })
    }
  })
  return flatRoutes
}

export default userStore
